/*

 * Licensed to the Apache Software Foundation (ASF) under one

 * or more contributor license agreements.  See the NOTICE file

 * distributed with this work for additional information

 * regarding copyright ownership.  The ASF licenses this file

 * to you under the Apache License, Version 2.0 (the

 * "License"); you may not use this file except in compliance

 * with the License.  You may obtain a copy of the License at

 *

 *     http://www.apache.org/licenses/LICENSE-2.0

 *

 * Unless required by applicable law or agreed to in writing, software

 * distributed under the License is distributed on an "AS IS" BASIS,

 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

 * See the License for the specific language governing permissions and

 * limitations under the License.

 */

package com.bff.gaia.unified.sdk.extensions.sql.impl;



import org.apache.calcite.adapter.java.JavaTypeFactory;

import org.apache.calcite.config.CalciteConnectionConfig;

import org.apache.calcite.jdbc.CalciteConnection;

import org.apache.calcite.jdbc.CalcitePrepare;

import org.apache.calcite.linq4j.Enumerator;

import org.apache.calcite.linq4j.Queryable;

import org.apache.calcite.linq4j.tree.Expression;

import org.apache.calcite.schema.SchemaPlus;



import java.lang.reflect.Type;

import java.sql.*;

import java.util.Map;

import java.util.Properties;

import java.util.concurrent.Executor;



/**

 * Abstract wrapper for {@link CalciteConnection} to simplify extension.

 *

 * <p>Calcite JDBC model lacks convenient Connection class to extend that would also be supported by

 * its factories without significant copy-pasting.

 *

 * <p>The purpose of this class is to hide the delegation logic from the children classes ({@link

 * JdbcConnection}) to make them cleaner and easier to read. It has no functional significance.

 *

 * <p>This class only delegates to the underlying {@link CalciteConnection}, all added or modified

 * functionality should go into into subclasses.

 *

 * <p>Ultimately a patch to Calcite can be made to simplify this logic.

 */

public abstract class CalciteConnectionWrapper implements CalciteConnection {

  private CalciteConnection connection;



  protected CalciteConnectionWrapper(CalciteConnection connection) {

    this.connection = connection;

  }



  protected CalciteConnection connection() {

    return connection;

  }



  @Override

  public SchemaPlus getRootSchema() {

    return connection.getRootSchema();

  }



  @Override

  public JavaTypeFactory getTypeFactory() {

    return connection.getTypeFactory();

  }



  @Override

  public Properties getProperties() {

    return connection.getProperties();

  }



  @Override

  public Statement createStatement() throws SQLException {

    return connection.createStatement();

  }



  @Override

  public PreparedStatement prepareStatement(String sql) throws SQLException {

    return connection.prepareStatement(sql);

  }



  @Override

  public CallableStatement prepareCall(String sql) throws SQLException {

    return connection.prepareCall(sql);

  }



  @Override

  public String nativeSQL(String sql) throws SQLException {

    return connection.nativeSQL(sql);

  }



  @Override

  public void setAutoCommit(boolean autoCommit) throws SQLException {

    connection.setAutoCommit(autoCommit);

  }



  @Override

  public boolean getAutoCommit() throws SQLException {

    return connection.getAutoCommit();

  }



  @Override

  public void commit() throws SQLException {

    connection.commit();

  }



  @Override

  public void rollback() throws SQLException {

    connection.rollback();

  }



  @Override

  public void close() throws SQLException {

    connection.close();

  }



  @Override

  public boolean isClosed() throws SQLException {

    return connection.isClosed();

  }



  @Override

  public DatabaseMetaData getMetaData() throws SQLException {

    return connection.getMetaData();

  }



  @Override

  public void setReadOnly(boolean readOnly) throws SQLException {

    connection.setReadOnly(readOnly);

  }



  @Override

  public boolean isReadOnly() throws SQLException {

    return connection.isReadOnly();

  }



  @Override

  public void setCatalog(String catalog) throws SQLException {

    connection.setCatalog(catalog);

  }



  @Override

  public String getCatalog() throws SQLException {

    return connection.getCatalog();

  }



  @Override

  public void setTransactionIsolation(int level) throws SQLException {

    connection.setTransactionIsolation(level);

  }



  @Override

  public int getTransactionIsolation() throws SQLException {

    return connection.getTransactionIsolation();

  }



  @Override

  public SQLWarning getWarnings() throws SQLException {

    return connection.getWarnings();

  }



  @Override

  public void clearWarnings() throws SQLException {

    connection.clearWarnings();

  }



  @Override

  public Statement createStatement(int resultSetType, int resultSetConcurrency)

      throws SQLException {

    return connection.createStatement(resultSetType, resultSetConcurrency);

  }



  @Override

  public PreparedStatement prepareStatement(String sql, int resultSetType, int resultSetConcurrency)

      throws SQLException {

    return connection.prepareStatement(sql, resultSetType, resultSetConcurrency);

  }



  @Override

  public CallableStatement prepareCall(String sql, int resultSetType, int resultSetConcurrency)

      throws SQLException {

    return connection.prepareCall(sql, resultSetType, resultSetConcurrency);

  }



  @Override

  public Map<String, Class<?>> getTypeMap() throws SQLException {

    return connection.getTypeMap();

  }



  @Override

  public void setTypeMap(Map<String, Class<?>> map) throws SQLException {

    connection.setTypeMap(map);

  }



  @Override

  public void setHoldability(int holdability) throws SQLException {

    connection.setHoldability(holdability);

  }



  @Override

  public int getHoldability() throws SQLException {

    return connection.getHoldability();

  }



  @Override

  public Savepoint setSavepoint() throws SQLException {

    return connection.setSavepoint();

  }



  @Override

  public Savepoint setSavepoint(String name) throws SQLException {

    return connection.setSavepoint(name);

  }



  @Override

  public void rollback(Savepoint savepoint) throws SQLException {

    connection.rollback(savepoint);

  }



  @Override

  public void releaseSavepoint(Savepoint savepoint) throws SQLException {

    connection.releaseSavepoint(savepoint);

  }



  @Override

  public Statement createStatement(

      int resultSetType, int resultSetConcurrency, int resultSetHoldability) throws SQLException {

    return connection.createStatement(resultSetType, resultSetConcurrency, resultSetHoldability);

  }



  @Override

  public PreparedStatement prepareStatement(

      String sql, int resultSetType, int resultSetConcurrency, int resultSetHoldability)

      throws SQLException {

    return connection.prepareStatement(

        sql, resultSetType, resultSetConcurrency, resultSetHoldability);

  }



  @Override

  public CallableStatement prepareCall(

      String sql, int resultSetType, int resultSetConcurrency, int resultSetHoldability)

      throws SQLException {

    return connection.prepareCall(sql, resultSetType, resultSetConcurrency, resultSetHoldability);

  }



  @Override

  public PreparedStatement prepareStatement(String sql, int autoGeneratedKeys) throws SQLException {

    return connection.prepareStatement(sql, autoGeneratedKeys);

  }



  @Override

  public PreparedStatement prepareStatement(String sql, int[] columnIndexes) throws SQLException {

    return connection.prepareStatement(sql, columnIndexes);

  }



  @Override

  public PreparedStatement prepareStatement(String sql, String[] columnNames) throws SQLException {

    return connection.prepareStatement(sql, columnNames);

  }



  @Override

  public Clob createClob() throws SQLException {

    return connection.createClob();

  }



  @Override

  public Blob createBlob() throws SQLException {

    return connection.createBlob();

  }



  @Override

  public NClob createNClob() throws SQLException {

    return connection.createNClob();

  }



  @Override

  public SQLXML createSQLXML() throws SQLException {

    return connection.createSQLXML();

  }



  @Override

  public boolean isValid(int timeout) throws SQLException {

    return connection.isValid(timeout);

  }



  @Override

  public void setClientInfo(String name, String value) throws SQLClientInfoException {

    connection.setClientInfo(name, value);

  }



  @Override

  public void setClientInfo(Properties properties) throws SQLClientInfoException {

    connection.setClientInfo(properties);

  }



  @Override

  public String getClientInfo(String name) throws SQLException {

    return connection.getClientInfo(name);

  }



  @Override

  public Properties getClientInfo() throws SQLException {

    return connection.getClientInfo();

  }



  @Override

  public Array createArrayOf(String typeName, Object[] elements) throws SQLException {

    return connection.createArrayOf(typeName, elements);

  }



  @Override

  public Struct createStruct(String typeName, Object[] attributes) throws SQLException {

    return connection.createStruct(typeName, attributes);

  }



  @Override

  public void setSchema(String schema) throws SQLException {

    connection.setSchema(schema);

  }



  @Override

  public String getSchema() throws SQLException {

    return connection.getSchema();

  }



  @Override

  public void abort(Executor executor) throws SQLException {

    connection.abort(executor);

  }



  @Override

  public void setNetworkTimeout(Executor executor, int milliseconds) throws SQLException {

    connection.setNetworkTimeout(executor, milliseconds);

  }



  @Override

  public int getNetworkTimeout() throws SQLException {

    return connection.getNetworkTimeout();

  }



  @Override

  public CalciteConnectionConfig config() {

    return connection.config();

  }



  @Override

  public CalcitePrepare.Context createPrepareContext() {

    return connection.createPrepareContext();

  }



  @Override

  public <T> T unwrap(Class<T> iface) throws SQLException {

    return connection.unwrap(iface);

  }



  @Override

  public boolean isWrapperFor(Class<?> iface) throws SQLException {

    return connection.isWrapperFor(iface);

  }



  @Override

  public <T> Queryable<T> createQuery(Expression expression, Class<T> rowType) {

    return connection.createQuery(expression, rowType);

  }



  @Override

  public <T> Queryable<T> createQuery(Expression expression, Type rowType) {

    return connection.createQuery(expression, rowType);

  }



  @Override

  public <T> T execute(Expression expression, Class<T> type) {

    return connection.execute(expression, type);

  }



  @Override

  public Object execute(Expression expression, Type type) {

    return connection.execute(expression, type);

  }



  @Override

  public <T> Enumerator<T> executeQuery(Queryable<T> queryable) {

    return connection.executeQuery(queryable);

  }

}